package com.group.itms.routes.map;

import java.util.List;

import pl.polidea.view.ZoomView;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.ImageView;

import com.group.itms.routes.R;
import com.group.itms.routes.utils.TapDetector;
import com.group.itms.routes.utils.TapDetector.OnTapListener;

public class OfflineMapView extends ZoomView implements OnTapListener {

	private OfflineMap mOfflineMap = new OfflineMap();
	private Bitmap mMyLocationBmp;

	private TapDetector mTapDetector;
	private float mClickTreshold;
	private Bitmap mMapBmp;

	public OfflineMapView(Context context) {
		super(context);
		mOfflineMap.setMapView(this);
		mMyLocationBmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_my_location);
		mTapDetector = new TapDetector(this);
		mClickTreshold = getTapThreshold(0.17f);
		setMaxZoom(7);
	}

	private float getTapThreshold(float inches) {
		DisplayMetrics dm = getDIsplayMetrics();
		return inches * dm.densityDpi;
	}

	private DisplayMetrics getDIsplayMetrics() {
		DisplayMetrics dm = new DisplayMetrics();
		WindowManager wm = (WindowManager) getContext().getSystemService(
				Context.WINDOW_SERVICE);
		wm.getDefaultDisplay().getMetrics(dm);
		return dm;
	}

	public void setMapImage(Bitmap bmp) {
		mMapBmp = bmp;
		ImageView iv = new ImageView(getContext());
		iv.setImageBitmap(bmp);
		addView(iv);
	}

	public OfflineMap getOfflineMap() {
		return mOfflineMap;
	}

	public Projection getProjection() {
		if (mOfflineMap != null) {
			return mOfflineMap.getProjection();
		}
		return null;
	}

	@Override
	protected void dispatchDraw(Canvas canvas) {
		super.dispatchDraw(canvas);
		drawSelf(canvas);
	}

	private void drawSelf(Canvas canvas) {
		int w = mMapBmp.getWidth();
		int h = mMapBmp.getHeight();
		int hdw = (getWidth() - w) / 2;
		
		Projection p = getProjection();
		p.setZoom(getZoom());
		p.setZoomX(getZoomFocusX() - hdw * getZoom());
		p.setZoomY(getZoomFocusY());
		p.setWidth(w);
		p.setHeight(h);

//		canvas.save();
		canvas.translate(hdw, 0);
		
		List<Layer> vLayers = mOfflineMap.getLayers();
		for (Layer l : vLayers) {
			if (l.isVisible()) {
				l.draw(canvas);
			}
		}

		PointD myLocation = mOfflineMap.getMyLocation();
		if (myLocation != null) {
			PointD pf = p.convertToScreen(myLocation);
			canvas.drawBitmap(mMyLocationBmp, (float)pf.x, (float)pf.y, null);
		}
		canvas.restore();
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		boolean a = mTapDetector.onTouchEvent(ev);
		boolean b = super.dispatchTouchEvent(ev); 
		return a || b; 
	}

	@Override
	public boolean onTap(float x, float y) {
		Marker m = getNearestMarker(x, y);
		if (m != null && m.screenDistance(getProjection(), x, y) <= mClickTreshold) {
			m.performClick();
			return true;
		}
		return false;
	}

	private Marker getNearestMarker(float x, float y) {
		List<Layer> layers = mOfflineMap.getLayers();
		Marker nM = null;
		for (Layer l : layers) {
			if (!l.isVisible()) {
				continue;
			}
			Marker m = l.getNearestMarkerToScreenPoint(x, y);
			if (m == null) {
				continue;
			}
			if (nM == null) {
				nM = m;
			} else if (m.screenDistance(getProjection(), x, y) < nM
					.screenDistance(getProjection(), x, y)) {
				nM = m;
			}
		}
		return nM;
	}
}
